package cn.chrilwe.pigpig.im.service;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;

import cn.chrilwe.pigpig.im.config.ServerConfig;
import cn.chrilwe.pigpig.im.ex.ClientConnectionDetailNullPointExeption;
import cn.chrilwe.pigpig.im.model.ClientConnectDetail;
import cn.chrilwe.pigpig.im.model.TokenStore;
import cn.chrilwe.pigpig.im.service.util.Oauth2Util;

/**
 * 
 * @author chrilwe
 * 2020-8-12
 */
@Service
public class ClientService {
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@Autowired
	private ServerConfig serverConfig;

	//客户端连接到当前服务器，在Redis生成一个连接信息
	//hash格式（roomid，clientid，ClientConnectDetail）
	public void setClientConnectionDetail(ClientConnectDetail detail) {
		if(detail != null && StringUtils.isNotEmpty(detail.getRoomId()) && StringUtils.isNotEmpty(detail.getClientId())) {
			String roomId = detail.getRoomId();
			String clientId = detail.getClientId();
			String str = (String)stringRedisTemplate.opsForHash().get(roomId, clientId);
			if(StringUtils.isEmpty(str)) {
				stringRedisTemplate.opsForHash().put(roomId, clientId, JSON.toJSONString(detail));
			}
		}
	}

	public void closeConnect(String roomId, String clientId) {
		List<String> shards = serverConfig.getShards();
		String serverName = serverConfig.getServerName();
		stringRedisTemplate.opsForHash().delete(roomId, clientId);
		String clientIdListStr = (String)stringRedisTemplate.opsForHash().get(roomId, serverName);
		List<String> clientIdList = null;
		if(StringUtils.isNotEmpty(clientIdListStr)) {
			clientIdList = JSON.parseArray(clientIdListStr, String.class);
			boolean contains = clientIdList.contains(clientId);
			if(contains) {
				clientIdList.remove(clientId);
				stringRedisTemplate.opsForHash().put(roomId, serverName, JSON.toJSONString(clientIdList));
			} else {
				removeShards(shards, roomId, clientIdListStr);
			}
		} else {
			removeShards(shards, roomId, clientIdListStr);
		}
		
	}
	
	protected void removeClientConnectDetail(String token) {
		String s = stringRedisTemplate.opsForValue().get(token);
		if(!StringUtils.isEmpty(s)) {
			TokenStore store = JSON.parseObject(s, TokenStore.class);
			ClientConnectDetail detail = Oauth2Util.parse(store);
			stringRedisTemplate.delete(detail.getUsername());
		}
	}
	
	protected void removeShards(List<String> shards, String roomId, String clientId) {
		if(shards != null && shards.size() > 0) {
			for(String shard : shards) {
				String clientIdListStr = (String)stringRedisTemplate.opsForHash().get(roomId, shard);
				if(StringUtils.isNotEmpty(clientIdListStr)) {
					List<String> clientIdList = JSON.parseArray(clientIdListStr, String.class);
					boolean contains1 = clientIdList.contains(clientId);
					if(!contains1) {
						clientIdList.remove(clientId);
						stringRedisTemplate.opsForHash().put(roomId, shard, JSON.toJSONString(clientIdList));
						break;
					}
				}
			}
		}
	}
}
